import iapws
# from yangke.performance.basic_para import *
from iapws.iapws97 import IAPWS97
from iapws.iapws95 import IAPWS95


def get_p_by_ht(h, t):
    """
    根据h和t求p

    :param h: 焓，单位为 kJ/kg
    :param t: 温度，单位为 K
    :return: 压力，单位为 MPa
    """
    # 因为IAPWS97不能根据 焓 和 温度 求 压力，这里借助IAPWS95进行查找求解
    # 即多次计算 get_h_by_pt，对比计算的焓值与给定焓值相等则返回对应的p
    p = IAPWS95(h=h, T=t).P
    h_1 = get_h_by_pt(p=p, t=t)
    if h_1 > h:  # 温度不变时，压力越大，焓越低，考虑绝热管道的蒸汽流动，等焓，pt都降低
        # 说明估计的p偏小
        p_min = p
        p_max = p + 0.01
        while get_h_by_pt(p=p_max, t=t) > h:
            p_max = p_max + 0.01

    else:
        # 说明估计的p偏大
        p_max = p
        p_min = p - 0.01
        while get_h_by_pt(p=p_min, t=t) < h:
            p_min = p_min - 0.01
    # 真实的压力值位于p_min和p_max之间，二分法求解
    p_ave = (p_min + p_max) / 2
    h0 = get_h_by_pt(p=p_ave, t=t)
    while abs(h0 - h) > 0.000000001 and p_max - p_min > 0.000000001:
        if h0 > h:
            p_min = p_ave
        else:
            p_max = p_ave
        p_ave = (p_min + p_max) / 2
        h0 = get_h_by_pt(p=p_ave, t=t)

    return p_ave


def get_h_by_pt(p, t):
    """
    根据p和t求h

    :param p: 压力，单位为 MPa
    :param t: 温度，单位为 K
    :return: 焓，单位为 kJ/kg
    """
    h2o = IAPWS97(P=p, T=t)
    return h2o.h


def get_t_by_hp(h, p) -> "返回单位为K的温度":
    """
    根据h和p求t

    :param h: 焓，单位为 kJ/kg
    :param p: 压力，单位为 MPa
    :return: 温度，单位为 K
    """
    h2o = iapws.iapws97.IAPWS97_Ph(P=p, h=h)
    return h2o.T


def get_h_by_px(p, x):
    """
    根据p和x求h

    :param p: 压力，单位为 MPa
    :param x: 蒸汽干度
    :return: 焓，单位为 kJ/kg
    """
    h2o = iapws.iapws97.IAPWS97_Px(P=p, x=x)
    return h2o.h
